package com.k.kc.util.tree.demo1;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 *
 * @param <T>
 *
 * @author test
 */
public class TreeBuildUtil<T extends BaseTreeNode> {

    private final Map<String,T> allTreeNodeMap;

    public static <T extends BaseTreeNode> List<T> buildTreeDTO(List<T> allTreeNodeList, List<T> currentTreeNodeList) {
        return new TreeBuildUtil<>(allTreeNodeList).buildTree(currentTreeNodeList);
    }

    public TreeBuildUtil(List<T> allTreeNodeList) {
        this.allTreeNodeMap = allTreeNodeList.stream().collect(Collectors.toMap(T::getCurrentUnionKey, node->node));
    }

    /**
     * 构建树结构 根集合 下级集合 如果currentRootNode为空 从传递进来所有的节点中获取
     * @title buildTree
     * @version 3.0.1_ziyang
     * @author songqinglong 210944941
     * @param currentRootNode
     * @updateTime 2022/5/25 下午1:56
     * @return: java.util.List<com.command.center.smp.cache.dto.BaseTreeNode<org.apache.poi.ss.formula.functions.T>>
     * @throws
     */
    public List<T> buildTree(List<T> currentRootNode) {
        List<T> treeNodeList = new ArrayList<>();
        List<T> rootNodeList;
        if(currentRootNode.size() > 0){
            rootNodeList = currentRootNode;
        }else{
            rootNodeList = getTreeRoot();
        }
        rootNodeList.sort(Comparator.comparing(T::getSort));
        for (T rootNode : rootNodeList) {
            fillChildren(rootNode);
            treeNodeList.add(rootNode);
        }
        return treeNodeList;
    }

    /**
     * 填充子集
     * @title fillChildren
     * @version 3.0.1_ziyang
     * @author songqinglong 210944941
     * @param parentTreeNode
     * @updateTime 2022/5/25 下午1:59
     * @throws
     */
    public void fillChildren(BaseTreeNode parentTreeNode) {
        List<T> children = getChildTreeNodeList(parentTreeNode);
        parentTreeNode.setLeaf(Boolean.TRUE);
        if (!children.isEmpty()) {
            for (BaseTreeNode child : children) {
                fillChildren(child);
            }
            parentTreeNode.setChildren(children);
            parentTreeNode.setLeaf(Boolean.FALSE);
        }
    }

    /**
     * 根据父节点 查询所有子节点
     * @title getChildOrgTreeNodeDTOs
     * @version 3.0.1_ziyang
     * @author songqinglong 210944941
     * @param parentTreeNode
     * @updateTime 2022/5/25 下午2:01
     * @return: java.util.List<com.command.center.smp.cache.dto.BaseTreeNode<org.apache.poi.ss.formula.functions.T>>
     * @throws
     */
    public List<T> getChildTreeNodeList(BaseTreeNode parentTreeNode) {
        List<T> childTreeNodeList = new ArrayList<>();
        allTreeNodeMap.forEach((currentKey,node)->{
            if (parentTreeNode.getCurrentUnionKey().equals(node.getParentUnionKey()) && !node.getParentUnionKey().equals(node.getCurrentUnionKey())) {
                childTreeNodeList.add(node);
            }
        });
        childTreeNodeList.sort(Comparator.comparing(T::getSort));
        return childTreeNodeList;
    }

    /**
     * 获取根节点集合
     * @title getTreeRoot
     * @version 3.0.1_ziyang
     * @author songqinglong 210944941
     * @updateTime 2022/5/25 下午1:54
     * @return: java.util.List<com.command.center.smp.cache.dto.BaseTreeNode<org.apache.poi.ss.formula.functions.T>>
     * @throws
     */
    public List<T> getTreeRoot() {
        List<T> rootTreeNodeList = new ArrayList<>();
        allTreeNodeMap.forEach((currentKey,node)->{
            if (rootOrgTreeNodeDTO(node)) {
                rootTreeNodeList.add(node);
            }
        });
        return rootTreeNodeList;
    }
    /**
     * 判断是否为根节点 当前判断无上级为根节点
     * @title rootOrgTreeNodeDTO
     * @version 3.0.1_ziyang
     * @author songqinglong 210944941
     * @param treeNode
     * @updateTime 2022/5/25 下午1:54
     * @return: boolean
     * @throws
     */
    public boolean rootOrgTreeNodeDTO(BaseTreeNode treeNode) {
        boolean isRootTreeNodeDTO = true;
        if(allTreeNodeMap.containsKey(treeNode.getParentUnionKey()) && !treeNode.getCurrentUnionKey().equals(treeNode.getParentUnionKey())){
            isRootTreeNodeDTO = false;
        }
        return isRootTreeNodeDTO;
    }

}
